package com.guosheng.nio;

import org.apache.ibatis.annotations.Select;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class NIOClient {

    //标识数字
    private static int flag = 0;
    //缓冲区大小
    private static int BLOCK = 4096;
    //接受数据缓冲区
    private static ByteBuffer receiveBuffer = ByteBuffer.allocate(BLOCK);
    //发送数据缓冲区
    private static ByteBuffer sendBuffer = ByteBuffer.allocate(BLOCK);
    //服务器端地址
    private final static InetSocketAddress SERVER_ADDRESS = new InetSocketAddress("127.0.0.1",7070);

    public static void main(String[] args) throws Exception{
        //打开socket通道
        SocketChannel socketChannel = SocketChannel.open();
        //设置为非阻塞方式
        socketChannel.configureBlocking(false);
        //打开选择器
        Selector selector = Selector.open();
        //注册链接服务端socket动作，连接事件
        socketChannel.register(selector, SelectionKey.OP_CONNECT);
        //连接
        socketChannel.connect(SERVER_ADDRESS);

        Set<SelectionKey> set;
        Iterator<SelectionKey> it;
        SelectionKey key;
        SocketChannel client;
        String receiveText;
        String sendText;
        int count = 0;

        while(true){
            //选择一组键，其相应的通道已为i/o操作准备就绪
            //此方法执行处于阻塞模式的选择操作
            selector.select();
            //返回此选择器的已选择键集
            set = selector.selectedKeys();
            it = set.iterator();
            while(it.hasNext()){
                key = it.next();
                if(key.isConnectable()){
                    System.out.println("client connect");
                    client = (SocketChannel) key.channel();
                    //判断此通道上是否正在进行连接操作
                    //完成套接字通道的连接过程
                    if(client.isConnectionPending()){
                        client.finishConnect();
                        System.out.println("完成连接！");
                        sendBuffer.clear();
                        sendBuffer.put("hello,server".getBytes());
                        sendBuffer.flip();
                        client.write(sendBuffer);
                    }
                    client.register(selector,SelectionKey.OP_READ);
                }else if(key.isReadable()){
                    client = (SocketChannel) key.channel();
                    //将缓冲区清空，以备下次读取
                    receiveBuffer.clear();
                    //读取服务器发送来的数据到缓冲区中
                    count = client.read(receiveBuffer);
                    if(count > 0){
                        receiveText = new String(receiveBuffer.array(),0,count,"utf-8");
                        System.out.println("客户端接受服务端数据是---：" + receiveText);
                        client.register(selector, SelectionKey.OP_WRITE);
                    }
                }else if(key.isWritable()){
                    sendBuffer.clear();
                    client = (SocketChannel) key.channel();
                    sendText = "message from client --" + flag ++;
                    sendBuffer.put(sendText.getBytes());
                    //将缓冲区各标志复位，因为向里面put数据标志被改变，要想从中读取数据发向服务器，就要复位
                    sendBuffer.flip();
                    client.register(selector,SelectionKey.OP_READ);
                }
            }
            set.clear();
        }

    }


}
